<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>偏振光实验 - 马吕斯定律验证</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        
        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            line-height: 1.6;
            color: #333;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            overflow: hidden;
        }
        
        .header {
            background: linear-gradient(135deg, #2c3e50 0%, #3498db 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        
        .header h1 {
            font-size: 28px;
            margin-bottom: 10px;
        }
        
        .header p {
            opacity: 0.9;
            font-size: 16px;
            max-width: 800px;
            margin: 0 auto;
        }
        
        .content {
            padding: 30px;
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 30px;
        }
        
        @media (max-width: 768px) {
            .content {
                grid-template-columns: 1fr;
            }
        }
        
        .input-section {
            background: #f8f9fa;
            padding: 25px;
            border-radius: 10px;
            border-left: 5px solid #3498db;
        }
        
        .input-section h2 {
            color: #2c3e50;
            margin-bottom: 20px;
            text-align: center;
        }
        
        .data-table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 20px;
        }
        
        .data-table th {
            background: #3498db;
            color: white;
            padding: 12px;
            text-align: center;
            font-weight: bold;
        }
        
        .data-table td {
            padding: 10px;
            text-align: center;
            border-bottom: 1px solid #e0e0e0;
        }
        
        .data-table tr:nth-child(even) {
            background: #f0f0f0;
        }
        
        .data-table input {
            width: 90%;
            padding: 8px;
            border: 2px solid #ddd;
            border-radius: 5px;
            text-align: center;
            font-size: 14px;
        }
        
        .data-table input:focus {
            border-color: #3498db;
            outline: none;
        }
        
        .controls {
            text-align: center;
        }
        
        .calculate-btn {
            background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
            color: white;
            border: none;
            padding: 15px 30px;
            font-size: 18px;
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.3s;
            margin: 10px;
        }
        
        .calculate-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(39, 174, 96, 0.4);
        }
        
        .clear-btn {
            background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
            color: white;
            border: none;
            padding: 15px 30px;
            font-size: 18px;
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.3s;
            margin: 10px;
        }
        
        .clear-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(231, 76, 60, 0.4);
        }
        
        .result-section {
            background: #f8f9fa;
            padding: 25px;
            border-radius: 10px;
            border-left: 5px solid #e74c3c;
        }
        
        .result-section h2 {
            color: #2c3e50;
            margin-bottom: 20px;
            text-align: center;
        }
        
        .result-box {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 3px 10px rgba(0,0,0,0.1);
            margin-bottom: 20px;
        }
        
        .result-item {
            display: flex;
            justify-content: space-between;
            margin-bottom: 12px;
            padding: 8px 0;
            border-bottom: 1px solid #e0e0e0;
        }
        
        .result-item:last-child {
            border-bottom: none;
        }
        
        .result-label {
            font-weight: bold;
            color: #2c3e50;
        }
        
        .result-value {
            color: #e74c3c;
            font-weight: bold;
            font-family: 'Courier New', monospace;
        }
        
        .equation {
            background: #2c3e50;
            color: white;
            padding: 20px;
            border-radius: 8px;
            text-align: center;
            font-family: 'Courier New', monospace;
            font-size: 18px;
            margin: 20px 0;
        }
        
        .chart-container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 3px 10px rgba(0,0,0,0.1);
            margin-top: 20px;
        }
        
        .instructions {
            background: #fff3cd;
            border: 1px solid #ffeaa7;
            border-radius: 8px;
            padding: 20px;
            margin-top: 20px;
            grid-column: 1 / -1;
        }
        
        .instructions h3 {
            color: #856404;
            margin-bottom: 10px;
        }
        
        .instructions ul {
            margin-left: 20px;
        }
        
        .instructions li {
            margin-bottom: 5px;
        }
        
        .theory {
            background: #d1ecf1;
            border: 1px solid #bee5eb;
            border-radius: 8px;
            padding: 20px;
            margin-top: 20px;
            grid-column: 1 / -1;
        }
        
        .theory h3 {
            color: #0c5460;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🧪 偏振光实验 - 马吕斯定律验证</h1>
            <p>根据实验数据验证马吕斯定律：I = I₀cos²α，通过线性拟合分析实验精度</p>
        </div>
        
        <div class="content">
            <div class="input-section">
                <h2>📊 实验数据输入</h2>
                <table class="data-table">
                    <thead>
                        <tr>
                            <th>数据点</th>
                            <th>X = cos²α</th>
                            <th>Y = I/I<sub>m</sub></th>
                        </tr>
                    </thead>
                    <tbody id="dataTable">
                        <!-- 数据行将通过JavaScript动态生成 -->
                    </tbody>
                </table>
                
                <div class="controls">
                    <button class="calculate-btn" onclick="calculateLinearFit()">开始线性拟合计算</button>
                    <button class="clear-btn" onclick="clearAllData()">清空所有数据</button>
                </div>
            </div>
            
            <div class="result-section">
                <h2>📈 拟合结果分析</h2>
                <div class="result-box">
                    <div class="result-item">
                        <span class="result-label">线性拟合方程：</span>
                        <span class="result-value" id="equation">Y = kX + b</span>
                    </div>
                    <div class="result-item">
                        <span class="result-label">斜率 k：</span>
                        <span class="result-value" id="slope">0.0000</span>
                    </div>
                    <div class="result-item">
                        <span class="result-label">截距 b：</span>
                        <span class="result-value" id="intercept">0.0000</span>
                    </div>
                    <div class="result-item">
                        <span class="result-label">相关系数 R²：</span>
                        <span class="result-value" id="rSquared">0.0000</span>
                    </div>
                </div>
                
                <div class="equation" id="finalEquation">
                    I/I<sub>m</sub> = k·cos²α + b
                </div>
                
                <div class="chart-container">
                    <canvas id="regressionChart"></canvas>
                </div>
            </div>
            
            <div class="theory">
                <h3>🎯 实验原理 - 马吕斯定律</h3>
                <p><strong>马吕斯定律：</strong> I = I₀cos²α</p>
                <p>其中：</p>
                <ul>
                    <li>I：通过检偏器后的光强</li>
                    <li>I₀：入射到检偏器前的光强（最大光强）</li>
                    <li>α：起偏器与检偏器透振方向之间的夹角</li>
                </ul>
                <p>在实验中，我们测量 I/I₀ 与 cos²α 的关系，理论上应该得到一条斜率为1、截距为0的直线。</p>
            </div>
            
            <div class="instructions">
                <h3>💡 使用说明</h3>
                <ul>
                    <li>在表格中输入10组实验数据（X = cos²α, Y = I/I<sub>m</sub>）</li>
                    <li>点击"开始线性拟合计算"按钮进行数据分析</li>
                    <li>系统会自动计算线性回归方程和相关系数</li>
                    <li>图表将显示数据点和拟合直线</li>
                    <li>理想情况下，斜率应接近1，截距应接近0，R²应接近1</li>
                    <li>使用"清空所有数据"按钮可以重置输入</li>
                </ul>
            </div>
        </div>
    </div>

    <script>
        // 初始化数据表
        function initializeDataTable() {
            const table = document.getElementById('dataTable');
            table.innerHTML = '';
            
            for (let i = 1; i <= 10; i++) {
                const row = document.createElement('tr');
                row.innerHTML = `
                    <td>${i}</td>
                    <td><input type="number" id="x${i}" step="0.001" placeholder="0.000" min="0" max="1"></td>
                    <td><input type="number" id="y${i}" step="0.001" placeholder="0.000" min="0" max="1"></td>
                `;
                table.appendChild(row);
            }
        }
        
        // 获取实验数据
        function getExperimentData() {
            const data = [];
            for (let i = 1; i <= 10; i++) {
                const x = parseFloat(document.getElementById(`x${i}`).value);
                const y = parseFloat(document.getElementById(`y${i}`).value);
                
                if (!isNaN(x) && !isNaN(y)) {
                    data.push({ x, y });
                }
            }
            return data;
        }
        
        // 线性拟合计算（最小二乘法）
        function linearRegression(data) {
            const n = data.length;
            if (n < 2) {
                throw new Error('至少需要2个数据点进行线性拟合');
            }
            
            let sumX = 0, sumY = 0, sumXY = 0, sumX2 = 0;
            
            data.forEach(point => {
                sumX += point.x;
                sumY += point.y;
                sumXY += point.x * point.y;
                sumX2 += point.x * point.x;
            });
            
            const meanX = sumX / n;
            const meanY = sumY / n;
            
            // 计算斜率和截距
            const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
            const intercept = (sumY - slope * sumX) / n;
            
            // 计算相关系数 R²
            let ssTot = 0, ssRes = 0;
            data.forEach(point => {
                ssTot += Math.pow(point.y - meanY, 2);
                const predictedY = slope * point.x + intercept;
                ssRes += Math.pow(point.y - predictedY, 2);
            });
            
            const rSquared = 1 - (ssRes / ssTot);
            
            return {
                slope: slope,
                intercept: intercept,
                rSquared: rSquared,
                equation: `Y = ${slope.toFixed(4)}X + ${intercept.toFixed(4)}`
            };
        }
        
        // 主计算函数
        function calculateLinearFit() {
            try {
                const data = getExperimentData();
                
                if (data.length < 2) {
                    alert('请至少输入2组完整的数据！');
                    return;
                }
                
                // 进行线性拟合
                const result = linearRegression(data);
                
                // 显示结果
                document.getElementById('slope').textContent = result.slope.toFixed(4);
                document.getElementById('intercept').textContent = result.intercept.toFixed(4);
                document.getElementById('rSquared').textContent = result.rSquared.toFixed(4);
                document.getElementById('equation').textContent = result.equation;
                document.getElementById('finalEquation').innerHTML = 
                    `I/I<sub>m</sub> = ${result.slope.toFixed(4)}·cos²α + ${result.intercept.toFixed(4)}`;
                
                // 绘制图表
                drawRegressionChart(data, result);
                
            } catch (error) {
                alert('计算错误：' + error.message);
            }
        }
        
        // 绘制回归图表
        function drawRegressionChart(data, regressionResult) {
            const ctx = document.getElementById('regressionChart').getContext('2d');
            
            // 如果已有图表实例，先销毁
            if (window.regressionChartInstance) {
                window.regressionChartInstance.destroy();
            }
            
            // 生成拟合线的数据点
            const minX = Math.min(...data.map(p => p.x));
            const maxX = Math.max(...data.map(p => p.x));
            const lineData = [
                { x: minX, y: regressionResult.slope * minX + regressionResult.intercept },
                { x: maxX, y: regressionResult.slope * maxX + regressionResult.intercept }
            ];
            
            window.regressionChartInstance = new Chart(ctx, {
                type: 'scatter',
                data: {
                    datasets: [
                        {
                            label: '实验数据点',
                            data: data,
                            backgroundColor: 'rgba(52, 152, 219, 0.8)',
                            borderColor: 'rgba(52, 152, 219, 1)',
                            pointRadius: 6,
                            pointHoverRadius: 8
                        },
                        {
                            label: '线性拟合直线',
                            data: lineData,
                            type: 'line',
                            backgroundColor: 'rgba(231, 76, 60, 0.2)',
                            borderColor: 'rgba(231, 76, 60, 1)',
                            borderWidth: 2,
                            pointRadius: 0,
                            fill: false
                        }
                    ]
                },
                options: {
                    responsive: true,
                    plugins: {
                        title: {
                            display: true,
                            text: '偏振光实验 - 马吕斯定律验证',
                            font: { size: 16 }
                        },
                        tooltip: {
                            callbacks: {
                                label: function(context) {
                                    return `X: ${context.parsed.x.toFixed(3)}, Y: ${context.parsed.y.toFixed(3)}`;
                                }
                            }
                        }
                    },
                    scales: {
                        x: {
                            title: {
                                display: true,
                                text: 'X = cos²α',
                                font: { size: 14, weight: 'bold' }
                            },
                            min: 0,
                            max: 1
                        },
                        y: {
                            title: {
                                display: true,
                                text: 'Y = I/Iₘ',
                                font: { size: 14, weight: 'bold' }
                            },
                            min: 0,
                            max: 1
                        }
                    }
                }
            });
        }
        
        // 清空所有数据
        function clearAllData() {
            if (confirm('确定要清空所有数据吗？')) {
                for (let i = 1; i <= 10; i++) {
                    document.getElementById(`x${i}`).value = '';
                    document.getElementById(`y${i}`).value = '';
                }
                
                // 清空结果显示
                document.getElementById('slope').textContent = '0.0000';
                document.getElementById('intercept').textContent = '0.0000';
                document.getElementById('rSquared').textContent = '0.0000';
                document.getElementById('equation').textContent = 'Y = kX + b';
                document.getElementById('finalEquation').innerHTML = 'I/I<sub>m</sub> = k·cos²α + b';
                
                // 清除图表
                if (window.regressionChartInstance) {
                    window.regressionChartInstance.destroy();
                    window.regressionChartInstance = null;
                }
            }
        }
        
        // 页面加载时初始化
        document.addEventListener('DOMContentLoaded', function() {
            initializeDataTable();
        });
    </script>
</body>
</html>